package com.hdsx.validator.validate.processor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hdsx.jts.io.WKTUtil;
import com.hdsx.validator.validate.processor.jsonbean.Features;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;

public abstract class AbstractGeometryProcessor {
	private static Logger log=LoggerFactory.getLogger(AbstractGeometryProcessor.class);
	protected static  String url="http://192.168.0.112:8080/mapdata/rest/mapdata/search";
	static{
			try {
				InputStream is = AbstractGeometryProcessor.class.getResourceAsStream("/application.properties");
				Properties dbProps = new Properties();
				dbProps.load(is);
				url=dbProps.getProperty("validator");
				log.info("\n url:"+url);
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
	/**
	 *
	 * @param url 
	 * @return boolean
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	protected boolean doGet(String param) throws Exception
	{
		
		String flog="false";
		//String url2=URLEncoder.encode(url, "UTF-8");
		CloseableHttpClient httpclient = HttpClients.createDefault();
		//HttpGet httpGet= new HttpGet(url2+"?encodeURIComponent("+param+")");
		HttpGet httpGet= new HttpGet(url);
		CloseableHttpResponse httpResponse = httpclient.execute(httpGet);
		StatusLine statusLine= httpResponse.getStatusLine();
		if (statusLine.getStatusCode()<300) {
			 HttpEntity entity = httpResponse.getEntity();
			 System.out.println("httpEntity:"+entity);
			 InputStream inputStream= entity.getContent();
			 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));  
			 flog=reader.readLine();  
		}
	    if(httpResponse!=null){httpResponse.close();}
		return Boolean.getBoolean(flog);
	}
	/**
	 *
	 * @param url 
	 * @return boolean
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	protected Features doPost(String where,String geometry,int spatial,String layerName) throws Exception
	{
		CloseableHttpClient httpclient = HttpClients.createDefault();
	    HttpPost httpPost = new HttpPost(url);  
	    List<NameValuePair> nvps = new ArrayList<NameValuePair>();  
	    nvps.add(new BasicNameValuePair("where", where));  
	    nvps.add(new BasicNameValuePair("geometry", geometry)); 
	    nvps.add(new BasicNameValuePair("spatialRel", spatial+"")); 
	    nvps.add(new BasicNameValuePair("layerName", layerName)); 
	    System.out.println("layerName="+layerName+"where="+where+"geometry="+geometry+"spatialRel="+spatial);
	    httpPost.setEntity(new UrlEncodedFormEntity(nvps,"UTF-8"));  
	    HttpResponse httpResponse= httpclient.execute(httpPost); 
	    Features features=null;
	    if(httpResponse.getStatusLine().getStatusCode() == 200)  
        {  
            HttpEntity httpEntity = httpResponse.getEntity();  
            InputStream inputStream= httpEntity.getContent();
			ObjectMapper mapper = new ObjectMapper();  
			try
			{
				features=mapper.readValue(inputStream, Features.class);
			}
			catch(Exception e){
				throw new Exception(e);
			}
        }
	    else
	    {
	    	log.error("服务调用异常{}",httpResponse.getStatusLine().getStatusCode());
	    	throw new Exception(httpResponse.getStatusLine().getStatusCode()+"");
	    }
		return features;
	}
	protected boolean doPosts(String where,Geometry GeoB,int spatial,String layerNames) throws Exception
	{
		Features features=null;
		String [] layers=layerNames.split(",");
		//Geometry GeoA;
		for(String layerName:layers)
		{
			double meters=100;
			double radian=meters*(360/(2*Math.PI * 6378137.0));
			GeoB=GeoB.buffer(radian);
			features =doPost(where,GeoB.toText(),spatial,layerName);
			if(features==null)
			{
				return false;
			}
			if(features.getFeatures().size()>0)
			{
//				for(int i=0;i<features.getFeatures().size();i++)
//				{
//					GeoA=GeometryBuffer(features.getFeatures().get(i).getGeometry());
//					if(esriSpatialRel(GeoA,GeoB,spatial))
//					{
//						return true;
//					}
//				}
				return true;
			}
		}
		return false;
	}
	protected Geometry GeometryBuffer(String wkt){
		double meters=100;
		double radian=meters*(360/(2*Math.PI * 6378137.0));
		return WKTUtil.reader(wkt).buffer(radian);
	}
	protected boolean esriSpatialRel(Geometry shapeA,Geometry shapeB,int spatial)
	{
		log.info("判断shapeA:{}与shapeB{}关系{}",shapeA,shapeB,spatial);
		switch(spatial)
    	{
	    	case 8:
	    		return shapeA.contains(shapeB);
	    	case 6:
	    		return shapeA.crosses(shapeB);
	    	case 1:
	    		return shapeA.disjoint(shapeB);
	    	case 5:
	    		return shapeA.overlaps(shapeB);
	    	case 9:
	    		return shapeA.relate(shapeB, null);
	    	case 4:
	    		return shapeA.touches(shapeB);
	    	case 7:
	    		return shapeA.within(shapeB);
	    	default :return false;
    	}
	}
	protected boolean geometricRelation(String wkt1, String wkt2,int spatialRelEnum) throws Exception{
		// TODO Auto-generated method stub
		WKTReader reader = new WKTReader( );  
    	Geometry jts1=(Geometry) reader.read(wkt1);
    	Geometry jts2=(Geometry) reader.read(wkt2);
    	return esriSpatialRel(jts1,jts2,spatialRelEnum);
	}
}
